﻿using System;
using System.Collections.Generic;
using System.Linq;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Plugin.Shipping.ByWeightAndDistance.Domain;

namespace Nop.Plugin.Shipping.ByWeightAndDistance.Services
{
    public partial class ShippingByWeightAndDistanceService : IShippingByWeightAndDistanceService
    {
        #region Fields

        private readonly IRepository<ShippingByWeightAndDistanceRecord> _sbwdRepository;
        private readonly ICacheManager _cacheManager;

        #endregion

        #region Ctor

        public ShippingByWeightAndDistanceService(ICacheManager cacheManager,
            IRepository<ShippingByWeightAndDistanceRecord> sbwRepository)
        {
            this._cacheManager = cacheManager;
            this._sbwdRepository = sbwRepository;
        }

        #endregion

        #region Methods

        public virtual void DeleteShippingByWeightAndDistanceRecord(ShippingByWeightAndDistanceRecord shippingByWeightAndDistanceRecord)
        {
            if (shippingByWeightAndDistanceRecord == null)
                throw new ArgumentNullException("shippingByWeightAndDistanceRecord");

            _sbwdRepository.Delete(shippingByWeightAndDistanceRecord);
        }

        public virtual IList<ShippingByWeightAndDistanceRecord> GetAll()
        {
            var query = from sbw in _sbwdRepository.Table
                        orderby sbw.CountryId, sbw.ShippingMethodId, sbw.From
                        select sbw;
            var records = query.ToList();
            return records;
        }

        public virtual ShippingByWeightAndDistanceRecord FindRecord(int shippingMethodId, int countryId, decimal weight, decimal distance)
        {
            var query = from sbw in _sbwdRepository.Table
                        where (sbw.ShippingMethodId == shippingMethodId) && 
                              (weight >= sbw.From && weight <= sbw.To) && 
                              (distance >= sbw.FromDistance && distance <= sbw.ToDistance)
                        orderby sbw.CountryId, sbw.ShippingMethodId, sbw.From
                        select sbw;

            var existingRecords = query.ToList();

            //filter by country
            foreach (var sbw in existingRecords)
                if (countryId == sbw.CountryId)
                    return sbw;

            foreach (var sbw in existingRecords)
                if (sbw.CountryId == 0)
                    return sbw;

            return null;
        }

        public virtual ShippingByWeightAndDistanceRecord GetById(int shippingByWeightRecordId)
        {
            if (shippingByWeightRecordId == 0)
                return null;

            var record = _sbwdRepository.GetById(shippingByWeightRecordId);
            return record;
        }

        public virtual void InsertShippingByWeightAndDistanceRecord(ShippingByWeightAndDistanceRecord shippingByWeightAndDistanceRecord)
        {
            if (shippingByWeightAndDistanceRecord == null)
                throw new ArgumentNullException("shippingByWeightAndDistanceRecord");

            _sbwdRepository.Insert(shippingByWeightAndDistanceRecord);
        }

        public virtual void UpdateShippingByWeightAndDistanceRecord(ShippingByWeightAndDistanceRecord shippingByWeightAndDistanceRecord)
        {
            if (shippingByWeightAndDistanceRecord == null)
                throw new ArgumentNullException("shippingByWeightAndDistanceRecord");

            _sbwdRepository.Update(shippingByWeightAndDistanceRecord);
        }

        #endregion
    }
}
